<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>VS Code插件创作中文开发文档</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="description" content="Description" />
    <meta
      name="viewport"
      content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
    />
    <link
      rel="shortcut icon"
      href="https://raw.githubusercontent.com/Liiked/VS-Code-Extension-Doc-ZH/master/resources/favicon.ico"
      type="image/x-icon"
    />
    <link
      href="https://cdn.bootcdn.net/ajax/libs/docsify/4.12.1/themes/vue.min.css"
      rel="stylesheet"
    />
    <link
      href="https://cdn.bootcdn.net/ajax/libs/gitalk/1.7.2/gitalk.min.css"
      rel="stylesheet"
    />
    <script
      src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"
      defer
    ></script>
    <style>
      .markdown-section ul {
        padding-left: 2.5rem;
      }
    </style>
  </head>

  <body>
    <div id="app"></div>
    <script>
      const pipe =
        (...functions) =>
        (input) =>
          functions.reduce((acc, fn) => fn(acc), input);
      const repoMap = {
        github: "https://github.com/Liiked/VS-Code-Extension-Doc-ZH",
        gitee: 'https://gitee.com/liik/VS-Code-Extension-Doc-ZH'
      }
      const termMap = {
        github: "https://raw.githubusercontent.com/Liiked/VS-Code-Extension-Doc-ZH/master/docs/README.md",
        gitee: 'https://gitee.com/liik/VS-Code-Extension-Doc-ZH/raw/master/docs/README.md'
      }
      const host = window.location.host.split('.')[1]
      window.$docsify = {
        name: "",
        repo: repoMap[host],
        loadSidebar: true,
        loadNavbar: true,
        auto2top: true,
        search: {
          paths: "auto",
          placeholder: "开始搜索",
          depth: 4,
        },
        subMaxLevel: 2,
        copyCode: {
          buttonText: "复制到剪贴板",
          errorText: "复制错误",
          successText: "已复制",
        },
        plugins: [
          // 头部导航插件
          function (hook, vm) {
            let path;
            hook.beforeEach((content) => {
              path = vm.route.path;
              let getNav = new Promise((reslove, reject) => {
                let nav;
                let attempTimes = 0;
                let interval = setInterval(() => {
                  attempTimes += 1;
                  if (attempTimes > 20) {
                    clearInterval(interval);
                    reject();
                    return;
                  }
                  if (!nav) {
                    nav = document.querySelector(".app-nav");
                  } else {
                    clearInterval(interval);
                    reslove(nav);
                  }
                }, 1000);
              });

              Promise.all([getNav]).then((all) => {
                let nav = all[0];
                let originPage = Docsify.dom.create(
                  `div`,
                  `<div class="go-origin-doc"> <a href="https://code.visualstudio.com/api/${path}" target="_blank">原始文档</a> </div>`
                );
                Docsify.dom.appendTo(document.body, originPage);
              });
              return content;
            });
          },
          // 术语插件
          function (hook, vm) {
            const extractTermArray = /\n.+/g;
            const extractLink = /\(.+\)/g;
            const extractTitle = /\)\s*.+/g;
            const comma = /[，|,]/g;
            const colon = /[：|:]/g;

            hook.beforeEach((content) => {
              let req = new Promise((resolve, reject) => {
                if (vm.route.path === "/") {
                  resolve(content);
                  return;
                }
                Docsify.get(
                  termMap[host],
                  false,
                  null
                ).then((d) => {
                  let clearUnrealtedData = d.split("terms")[1];
                  const rawData = clearUnrealtedData.match(extractTermArray);
                  let getTerms = pipe(termMapFactory, termObjFactory);
                  let termsObject = getTerms(rawData);
                  let htmlContent = content;
                  htmlContent = transformContent(termsObject, htmlContent);
                  resolve(htmlContent);
                });
              });
              return req;
            });

            function termMapFactory(arr) {
              let termsCollection = [];
              return arr.map((e) => {
                let link = e.match(extractLink);
                if (link) {
                  let cleanLink = link[0].replace(/[\(|\)]/g, "");
                  let title = e.match(extractTitle)[0];
                  let [titleUnit, description] = getTitleAndDescript(title);
                  termsCollection = termsCollection.concat(titleUnit || []);
                  return {
                    cleanLink,
                    titleUnit,
                    description,
                  };
                }
              });
            }

            function termObjFactory(arr) {
              let termsObject = {};
              arr.forEach((e) => {
                if (!e) {
                  return;
                }
                const { titleUnit } = e;
                const title = titleUnit[0];
                const titleArrary = title.split("/");
                titleArrary.forEach((d) => {
                  termsObject[d] = e;
                });
              });
              return termsObject;
            }

            function getTitleAndDescript(str) {
              let cleanTitle = str
                .replace(/\)/g, "")
                .replace(/\s*/g, "")
                .replace(colon, "||");
              let [titleText, description] = cleanTitle.split("||");
              let titleUnit = titleText.replace(comma, " ").split(" ");
              return [titleUnit, description];
            }

            function templ(termsObject, originStr) {
              let { description = "", cleanLink } = termsObject[originStr];
              return `<span class="hover-tip">${originStr}
                <span class="tip-box">
                    <span class="no-margin"><a class="tips-title" href="${cleanLink}" target="_blank">${originStr}</a></span>
                    <span class="tips-content">${description}</span>
                </span>
              </span>`.replace(/(\n|\s{2,})/g, "");
            }

            function tansformHTML(content, termsObject, key) {
              let template = templ(termsObject, key);
              return content.replace(/\{\{0\}\}/g, template);
            }
            /***
             * 标记需要转换html的位置
             ***/
            function markHtml(content, index, length) {
              let left = content.substring(0, index);
              let right = content.substring(index + length, content.length);
              return left + "{{0}}" + right;
            }
            /***
             * 将文档中的术语转换为自定义格式
             ***/
            function transformContent(termsObject, html) {
              let exceptIdentifers = /(\/+|\]|\[|#|`|\=)/g;
              let ct = html;
              for (const key in termsObject) {
                if (termsObject.hasOwnProperty(key)) {
                  const e = termsObject[key];
                  const termReg = new RegExp(key, "g");
                  const termLen = key.length;
                  let findOne = termReg.exec(ct);
                  if (!findOne) {
                    continue;
                  }

                  while (findOne) {
                    const idx = findOne.index;
                    const str = ct.substring(idx - 14, idx + termLen + 4);
                    const context = str.replace(/\s+/g, "");
                    // test在处理的时候会遇到诡异的问题，因此用match替换
                    // const notConvertable = exceptIdentifers.test(context)
                    // 如 a = '` ###插件清单：`'
                    //    b = /\#/g
                    //    多次执行 b.test(a) -> true true true false true
                    const notConvertable = context.match(exceptIdentifers);

                    if (notConvertable) {
                      findOne = termReg.exec(ct);
                      continue;
                    }
                    ct = markHtml(ct, idx, termLen);
                    findOne = termReg.exec(ct);
                  }
                  ct = tansformHTML(ct, termsObject, key);
                }
              }
              return ct;
            }
          },
        ],
      };
    </script>
    <script
      type="text/javascript"
      src="https://cdn.jsdelivr.net/gh/Liiked/VS-Code-Extension-Doc-ZH/resources/docsify.js"
    ></script>
    <script src="https://cdn.bootcss.com/docsify/4.7.0/plugins/search.min.js"></script>
    <script src="https://cdn.bootcss.com/docsify/4.7.0/plugins/emoji.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/docsify/4.12.1/plugins/gitalk.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/gitalk/1.7.2/gitalk.min.js"></script>
    <script src="//unpkg.com/docsify-copy-code@2"></script>
    <script
      defer
      src="https://cdn.bootcdn.net/ajax/libs/prism/1.24.1/components/prism-typescript.min.js"
    ></script>
    <script
      defer
      src="https://cdn.bootcdn.net/ajax/libs/prism/1.24.1/components/prism-javascript.min.js"
    ></script>
    <script
      defer
      src="https://cdn.bootcdn.net/ajax/libs/prism/1.24.1/components/prism-json.min.js"
    ></script>
    <script
      defer
      src="https://cdn.bootcdn.net/ajax/libs/prism/1.24.1/components/prism-yaml.min.js"
    ></script>
    <script>
      const gitalk = new Gitalk({
        clientID: "9b16ded173ee4fa97e7a",
        clientSecret: "647586aeb30a27e714482aec08a9de9046bfd536",
        repo: "VS-Code-Extension-Doc-ZH",
        owner: "Liiked",
        admin: ["Liiked"],
        id: location.pathname,
        // facebook-like distraction free mode
        distractionFreeMode: false,
      });
    </script>
    <style type="text/css">
      .sidebar .sidebar-nav ul > li,
      .sidebar .sidebar-nav > ul > li > a {
        font-weight: bold;
        font-size: 15px;
        color: #364149;
      }

      .hover-tip {
        display: inline-block;
        position: relative;
        padding: 0 4px;
        color: #42b983;
        border-bottom-width: 2px;
        border-bottom-style: solid;
        border-bottom-color: white;
        transition: all 0.2s;
      }

      .hover-tip:hover {
        border-bottom-color: #42b983;
      }

      .hover-tip:hover .tip-box {
        transform: scale(1) translate(0, -2px);
        opacity: 1;
        max-height: 240px;
        padding: 1rem;
        transition: transform 0.2s, max-height 0.2s ease-in, opacity 0.2s;
        z-index: 999;
      }

      .hover-tip .tip-box {
        transform: scale(0) translate(100px, 100px);
        max-height: 0px;
        width: 240px;
        overflow: hidden;
        right: 0;
        bottom: 1.4rem;
        box-sizing: border-box;
        opacity: 0;
        border: 2px solid #42b983;
        position: absolute;
        background: white;
        transition: transform 0.2s;
      }

      .hover-tip > a {
        color: white;
      }

      .tip-box > * {
        display: block;
      }

      .tip-box .no-margin {
        margin: 0;
      }

      .tip-box .tips-title {
        font-size: 1rem;
        margin: 0;
      }

      .tip-box .tips-content {
        word-break: break-all;
        color: #364149;
        font-weight: normal;
        font-size: 0.8rem;
      }

      video {
        width: 100%;
      }

      /** 
     * 优化导航栏
     * **/

      .app-nav > li > ul > li {
        margin: 10px 0;
        margin-right: 16px;
      }

      .app-nav > ul > li > ul > li {
        padding: 10px;
        margin: 0;
      }

      .app-nav > ul > li > ul > li:hover {
        background: #1d4742;
      }

      .app-nav > ul > li:hover > ul {
        min-width: 100px;
        display: flex;
        padding: 10px;
        color: white;
        background: #0b6b62;
      }

      .app-nav li:hover > ul {
        overflow: visible;
      }

      .app-nav li:hover > ul > li {
        border-radius: 4px;
      }

      .app-nav li:hover > ul > li > ul {
        background: transparent;
      }

      .app-nav > ul > li > ul > li > ul {
        overflow: visible;
        position: initial;
        border: none;
      }

      .app-nav > ul > li > ul > li > ul > li {
        margin: 0;
        margin-bottom: 4px;
      }
      /* 查看原始文档 */
      .go-origin-doc {
        position: fixed;
        bottom: 10px;
        right: 10px;
        z-index: 100;
        background: #42b983;
        color: white;
        padding: 10px 20px;
        border-radius: 2em;
        filter: grayscale(0.6);
        opacity: 0.2;
        transition: all 0.4s;
      }
      .go-origin-doc:hover {
        opacity: 1;
        filter: grayscale(0);
      }
      .go-origin-doc a {
        color: white;
        font-style: normal;
        text-decoration: none;
      }
    </style>
  </body>
</html>
